<template>
  <div class="goodsinfo-container">
    <!-- 要实现动画的小球 -->
    <!-- 注意：钩子函数动画，这些钩子函数，都是通过事件绑定机制，绑定到 transition 元素上的 -->
    <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
      <div class="ball" v-show="ballFlag" ref="ball"></div>
    </transition>

    <!-- 商品轮播图区域 -->
    <div class="mui-card">
      <div class="mui-card-content">
        <div class="mui-card-content-inner">
          <swiper :lunbotuList="this.lunbotu" :isfull="false"></swiper>
        </div>
      </div>
    </div>

    <!-- 商品购买区域 -->
    <div class="mui-card">
      <div class="mui-card-header">{{ goodsinfo.title }}</div>
      <div class="mui-card-content">
        <div class="mui-card-content-inner">
          <p class="price">
            市场价：
            <del>￥{{ goodsinfo.market_price }}</del>&nbsp;&nbsp;销售价：
            <span class="now_price">￥{{ goodsinfo.sell_price }}</span>
          </p>
          <p>
            购买数量：
            <numbox @getcount="getSelectedCount" :max="goodsinfo.stock_quantity"></numbox>
            <!-- 注意： 这里 的 max 是库存量 -->
            <!-- 由于 goodsinfo 是通过 Ajax 动态获取回来的，但是，Ajax 是异步请求，需要消耗时间 -->
            <!-- 因此，可能会导致这样的情况： bobox 组件 先于 Ajax 渲染出来，此时， 组件被渲染的时候， goodsinfo 为 空对象，因此，传递到子组件中的 stock_quantity 是 undefined；  -->
            <!-- <nobox :max="goodsinfo.stock_quantity" @func="getSelectedCount"></nobox> -->
            <!-- <nobox :max="60"></nobox> -->
          </p>
          <p>
            <mt-button type="primary" size="small">立即购买</mt-button>
            <mt-button type="danger" size="small" @click="addToShopCart">加入购物车</mt-button>
          </p>
        </div>
      </div>
    </div>

    <!-- 商品参数区域 -->
    <div class="mui-card btnarea">
      <div class="mui-card-header">商品参数</div>
      <div class="mui-card-content">
        <div class="mui-card-content-inner">
          <p>商品货号：{{ goodsinfo.goods_no }}</p>
          <p>库存情况：{{ goodsinfo.stock_quantity }}件</p>
          <p>上架时间：{{ goodsinfo.add_time | dateFormat }}</p>
        </div>
      </div>
      <div class="mui-card-footer">
        <!-- <router-link :to="'/home/goodsdesc/' + goodsinfo.id">
            <mt-button type="primary" size="large" plain>图文介绍</mt-button>
        </router-link>-->

        <!-- 使用编程式导航，来实现路由页面的跳转 -->
        <!-- 编程式导航：就是使用JS的代码的方式，来实现路由的跳转 -->
        <!-- 元素导航：使用 router-link 元素实现的导航 -->
        <mt-button type="primary" size="large" plain @click="goDesc">图文介绍</mt-button>
        <mt-button type="danger" size="large" plain @click="goComment">商品评论</mt-button>
      </div>
    </div>
  </div>
</template>

<script>
// 导入轮播图组件
import swiper from "../subcomponents/swiper.vue";
// 导入 数字选择框 组件
import numbox from "../subcomponents/goodsinfo_numbox.vue";

export default {
  data() {
    return {
      id: this.$route.params.id, // 将路由参数对象中的 id 挂在到 data，方便后期调用
      lunbotu: [], //商品的轮播图数据
      goodsinfo: {}, // 商品的详情
      ballFlag: false, // 控制小球的显示与隐藏状态
      selectedCount: 1 // 用户选择的商品购买数量， 默认选中了一个商品
    };
  },
  created() {
    this.getlunbotu();
    this.getGoodsInfo();
  },
  methods: {
    getlunbotu() {
      // 获取轮播图的方法
      this.$http.get("api/getthumimages/" + this.id).then(result => {
        if (result.body.status === 0) {
          // 先循环轮播图数组的每一项，为 item 添加 img 属性，因为 轮播图 组件中，只认识 item.img; 而在 GoodsInfo.vue 中轮播图的图片参数是 item.img ,所以要将 img 改为 src 属性才能让统一的 swiper.vue 组件识别
          result.body.message.forEach(item => {
            item.img = item.src;
          });
          this.lunbotu = result.body.message;
        }
      });
    },
    getGoodsInfo() {
      // 获取商品的信息
      this.$http.get("api/goods/getinfo/" + this.id).then(result => {
        if (result.body.status === 0) {
          this.goodsinfo = result.body.message[0];
        }
      });
    },
    goDesc() {
      // 点击使用编程式导航跳转到 图文介绍页面
      // this.$route.push({ name:"goodsdesc", params:{ id } })
      this.$router.push("/home/goodsdesc/" + this.id);
    },
    goComment() {
      // 点击跳转到 评论页面
      // this.$route.push({ name:"goodscomment", params:{ id } })
      this.$router.push("/home/goodscomment/" + this.id);
    },
    addToShopCart() {
      // 添加到购物车
      this.ballFlag = !this.ballFlag;
      // 商品对象:{id:商品的id, count:要购买的数量, price:商品的单价, selected:false}
      // 拼接出一个，要保存到 store 中 car 数组里的 商品信息对象
      var goodsinfo = {
        id: this.id,
        count: this.selectedCount, // selectedCount 在 getSelectedCount(count) 方法中通过获取数字框子组件的值 发送了改变
        price: this.goodsinfo.sell_price,
        selected: true
      };
      // 调用 store 中的 mutations 来将商品加入购物车
      this.$store.commit("addToCar",goodsinfo);

      // 调用 mutations 中的 addToCar
      /* this.$store.commit("addToCar", {
        id: this.id,
        count: this.selectedCount
      }); */
      // 直接调用 mapMutaions 中映射出来的方法
    },
    beforeEnter(el) {
      // 入场动画开始之前，设置小球的起始状态
      el.style.transform = "translate(0, 0)";
    },
    enter(el, done) {
      // 入场动画结束之后，小球的终止状态
      //    transform：变换
      //    translate： 位移
      //    transition： 过渡效果
      el.offsetWidth; // 不设置就没有动画

      // 小球动画优化思路：
      // 1. 先分析导致 动画 不准确的 本质原因：我们把 小球 最终 位移到的 位置，已经局限在了某一分辨率下的 滚动条未滚动的情况下，
      // 2. 只要分辨率和 调试的时候不一样，或者 滚动条有一定的滚动距离之后，问题就出现了；
      // 3. 因此，我们经过分析，得到结论：不能把 位置的 横纵坐标 直接写死了，而是应该 根据不同情况，动态设计这个坐标值；
      // 4. 经过分析，得出解题思路：先得到 图标的 横纵 坐标，再得到 小球的 横纵坐标，然后 让 y 值 求差，x 值也求 差，得到 的结果，就是横纵坐标要位移的距离
      // 5. 如何 获取 徽标和小球的 位置？？？   domObject.getBoundingRect()

      // 获取小球的 在页面中的位置
      const ballPosition = this.$refs.ball.getBoundingClientRect(); // ball 是 小球样式中的 ref="ball"
      // badge 是 App.vue 中 购物车上的数字(购物车徽标)的id；由于 document.getElementById 方法不限于组件之间，所以可以用这种方法来代替从父组件 Qpp.vue 将 badge 的位置 该组件中
      const badgePosition = document
        .getElementById("badge")
        .getBoundingClientRect(); // 获取 徽标 在页面中的位置

      // 购物车徽标的距离顶部的距离 减去 小球初始位置距离顶部的距离 可以得到小球位移的纵坐标
      const xDist = badgePosition.left - ballPosition.left;
      // 购物车徽标的距离左边的距离 减去 小球初始位置距离左边的距离 可以得到小球位移的横坐标
      const yDist = badgePosition.top - ballPosition.top;

      // el.style.transform = "translate(93px, 230px)"; // 设置终止位置
      el.style.transform = `translate(${xDist}px, ${yDist}px)`; // 设置终止位置
      // el.style.transition = "all 1s ease"; // 过渡效果
      el.style.transition = "all 0.5s cubic-bezier(.4,-0.3,1,.68)"; // cubic-bezier 和 ease 一样都是过渡的动画效果
      // 当入场动画完成之后，需要手动调用一下 done 回调函数，直接跳过小球的出场动画
      done(); // 表示引用 afterEnter() 的方法
    },
    afterEnter(el) {
      // 入场动画完成之后的回调函数
      this.ballFlag = !this.ballFlag;
    },
    getSelectedCount(count) {
      // count 为 子组件 goodsinfo_numbox.vue 传递过来的参数
      // 当子组件把 选中的数量传递给父组件的时候，把选中的值保存到 data 上
      this.selectedCount = count;
      console.log("父组件中拿到了传递过来的count值为：" + this.selectedCount);
    }
  },
  components: {
    swiper,
    numbox
  }
};
</script>

<style lang="scss" scoped>
.goodsinfo-container {
  background-color: #eee;
  overflow: hidden; // div 距离顶部又一些距离,需要取消

  .now_price {
    font-size: 16px;
    color: red;
    font-weight: bold;
  }

  .mui-card-footer {
    display: block;
    button {
      margin: 15px 0;
    }
  }
}

.ball {
  width: 15px;
  height: 15px;
  background-color: red;
  border-radius: 50%;
  // 让小球脱离标准流
  position: absolute; // 小球把上面的框顶了下来，所以要加绝对定位
  z-index: 99; // 由于小球的层级不够，所以小球会被轮播图的样式 mui-card 覆盖，需要增加他的层级，让他覆盖在轮播图的上面
  left: 146px;
  top: 390px;
  // 将来小球要通过动画位移到的位置
  // transform: translate(93px, 230px);
}
</style>